package org.turl.objects;

import org.turl.annotations.instanceConverter;
import org.turl.annotations.convertible;
import org.turl.wrappers.RectangularToPolarMapper;

/**
 * Created by tonyx
 * Date: Dec 30, 2007
 * Time: 9:50:29 AM
 */
public class RectangularComplexNumber implements ComplexNumber, Navigable {
    protected double real;
    protected double img;

    // instanceConverter specifies the mapping, whereas convertible specifies that a mapping
    // does exists, and it is injected in a map of wrappers

    @convertible(contractClass=ComplexNumber.class)
    @instanceConverter(instanceConverterMap = RectangularToPolarMapper.class)
    public RectangularComplexNumber(double real, double img) {
        this.real=real;
        this.img = img;
    }

    public double getReal() {
        return real;
    }

    public double getImg() {
        return img;
    }


     /**
     * tree traversal equals implementation. Subclasses with extrafields should redefine _navigate and _compareFields
     */
    public boolean equals(Object other) {
        if (other == null) return false;
        if (other == this) return true;
        if (!(other instanceof ComplexNumber)) return false;
        return _navigate(other, false);
    }

    public boolean _navigate(Object other, boolean reversed) {
        if (other instanceof ComplexNumber && !reversed) {
            return ((Navigable) other)._navigate(this, true);
        } else {
            return _compareFields(other);
        }
    }

    private boolean _compareFields(Object other)
    {
        if (other instanceof ComplexNumber )
        {
            ComplexNumber rOther = (ComplexNumber)other;
            return !(this.real != rOther.getReal() || this.img != rOther.getImg());
        } else
            return false;
    }

   /*
   simpler, but weaker equals implementation. you can't use a getClass()
    public boolean equals(Object object)
    {
        if (!(object instanceof ComplexNumber))
            return false;
        ComplexNumber other = (ComplexNumber)object;
        return other.getReal()==real && other.getImg()==img;
    }
    */

    public int hashCode()
    {
        return ((int)(img+real))%37;
    }

    public String toString()
    {
        return "actual type: "+this.getClass().toString()+"real: "+this.getReal()+"; img: "+this.getImg()+ ";";
    }
}
